import pandas as pd
from pyecharts import options as opts
# 导入bokeh模块
from bokeh.plotting import figure
# 颜色模块
from bokeh.transform import factor_cmap
from bokeh.palettes import Spectral3
from bokeh.models import ColumnDataSource, FactorRange
from pyecharts import options as opts
from pyecharts.charts import *
from pyecharts.commons.utils import JsCode
from pyecharts.globals import ChartType, SymbolType


def read_data():
    return pd.read_excel("final_data.xlsx")

def biao():
    data = read_data()
    data.drop('职位信息', axis=1, inplace=True)
    data['平均工资'] = (data['最高工资'] + data['最低工资']) / 2
    return data

data=biao()

def zuigao():
    广州 = data[data['城市'].isin(['广州'])]
    广州最高工资 = 广州[广州['最高工资'] == 广州['最高工资'].max()]
    深圳 = data[data['城市'].isin(['深圳'])]
    深圳最高工资 = 深圳[深圳['最高工资'] == 深圳['最高工资'].max()]
    上海 = data[data['城市'].isin(['上海'])]
    上海最高工资 = 上海[上海['最高工资'] == 上海['最高工资'].max()]
    北京 = data[data['城市'].isin(['北京'])]
    北京最高工资 = 北京[北京['最高工资'] == 北京['最高工资'].max()]
    杭州 = data[data['城市'].isin(['杭州'])]
    杭州最高工资 = 杭州[杭州['最高工资'] == 杭州['最高工资'].max()]
    最高工资 = 广州最高工资.append([深圳最高工资, 上海最高工资, 北京最高工资, 杭州最高工资])
    城市最高工资 = 最高工资.drop_duplicates(subset='最高工资')
    # 准备x轴数据
    工资 = ['最高工资', '最低工资']
    cities = list(data['城市'].unique())
    cities_count = list(data['城市'].value_counts())
    zipped = zip(cities, cities_count)
    urban = [list(z) for z in zipped]
    max_city = urban[0:5]
    city_name = []
    for i in max_city:
        city_name.append(i[0])
    x = [(city, wages) for city in city_name for wages in 工资]
    # 准备y轴数据
    y = sum(zip(城市最高工资['最高工资'], 城市最高工资['最低工资']), ())
    # 准备ColumnDataSource
    source = ColumnDataSource(
        data=dict(
            x_axis=x,
            y_counts=y,
        )
    )
    # 准备tooltips 鼠标移入显示数据
    TOOLTIPS = [
        ("wage", "@y_counts"),
        ("地点", "@x_axis")]
    color = Spectral3
    # 画布
    p = figure(
        x_range=FactorRange(*x),
        plot_height=350,
        title="需求最高的5个城市企业最高工资差异（千/月）",
        tooltips=TOOLTIPS
    )
    # 绘制图形 vbar 垂直柱状图
    p.vbar(
        x='x_axis',
        top="y_counts",
        width=0.8,
        source=source,
        fill_color=factor_cmap('x_axis',
                               palette=color,
                               factors=工资,
                               start=1, end=2)
    )
    p.y_range.start = 0
    p.x_range.range_padding = 0.1
    p.xaxis.major_label_orientation = 1
    return p


def zuidi():
    广州 = data[data['城市'].isin(['广州'])]
    广州最低工资 = 广州[广州['最低工资'] == 广州['最低工资'].min()]
    深圳 = data[data['城市'].isin(['深圳'])]
    深圳最低工资 = 深圳[深圳['最低工资'] == 深圳['最低工资'].min()]

    上海 = data[data['城市'].isin(['上海'])]
    上海最低工资 = 上海[上海['最低工资'] == 上海['最低工资'].min()]

    北京 = data[data['城市'].isin(['北京'])]
    北京最低工资 = 北京[北京['最低工资'] == 北京['最低工资'].min()]

    杭州 = data[data['城市'].isin(['杭州'])]
    杭州最低工资 = 杭州[杭州['最低工资'] == 杭州['最低工资'].min()]
    最低工资 = 广州最低工资.append([深圳最低工资, 上海最低工资, 北京最低工资, 杭州最低工资])
    城市最低工资 = 最低工资.sort_values("最低工资", ascending=False).drop_duplicates("城市", keep='first').reset_index(drop=True)

    工资 = ['最高工资', '最低工资']
    cities = list(data['城市'].unique())
    cities_count = list(data['城市'].value_counts())
    zipped = zip(cities, cities_count)
    urban = [list(z) for z in zipped]
    max_city = urban[0:5]
    city_name = []
    for i in max_city:
        city_name.append(i[0])

    x = [(city, wages_min) for city in city_name for wages_min in 工资]
    y = sum(zip(城市最低工资['最高工资'], 城市最低工资['最低工资']), ())
    # 准备ColumnDataSource
    source = ColumnDataSource(
        data=dict(
            x_axis=x,
            y_counts=y,
        )
    )
    TOOLTIPS = [
        ("wage", "@y_counts"),
        ("地点", "@x_axis")]
    color = Spectral3
    p2 = figure(
        x_range=FactorRange(*x),
        plot_height=350,
        title="需求最高的5个城市企业最低工资差异(千/月)",
        tooltips=TOOLTIPS
    )
    p2.vbar(
        x='x_axis',
        top="y_counts",
        width=0.8,
        source=source,
        fill_color=factor_cmap('x_axis',
                               palette=color,
                               factors=工资,
                               start=1, end=2)
    )
    p2.y_range.start = 0
    p2.x_range.range_padding = 0.1
    p2.xaxis.major_label_orientation = 1
    return p2


def leixing():
    leixing = list(data['公司类型'].unique())
    leixing_count = list(data['公司类型'].value_counts())
    c = (Pie(init_opts=opts.InitOpts(width="800px", height="600px"))
        .add(
        series_name="公司类型",
        data_pair=[list(z) for z in zip(leixing, leixing_count)],
        radius=["50%", "70%"],
        label_opts=opts.LabelOpts(is_show=True, ),
    )
        .set_global_opts(legend_opts=opts.LegendOpts(pos_left="legft", orient="vertical"))
        .set_series_opts(
        tooltip_opts=opts.TooltipOpts(
            trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"
        ),
    )
    )
    return c


def custom_sort(guimo):
    sort_rule = [('少于50人', 0), ('50-150人', 1), ('150-500人', 2), ('500-1000人', 3), ('1000-5000人', 4), ('5000-10000人', 5),
                 ('10000人以上', 6)]
    sort_ls = []
    for i in guimo:
        for rule in sort_rule:
            if rule[0] in i:
                sort_ls.append((rule[1], i))
                break
    sort_ls.sort()
    return [i[1] for i in sort_ls]


def hangyexinzi():
    salary_average = data.groupby('所属行业')['平均工资'].mean().to_frame('平均工资').reset_index()
    salary_average['平均工资'] = salary_average['平均工资'].round(decimals=1)
    salary_average = salary_average.sort_values('平均工资', ascending=False)[:10]

    factors = salary_average['所属行业'].values.tolist()
    x = salary_average['平均工资'].values.tolist()

    fig = figure(
        title="所属行业平均薪资(千/月)",
        toolbar_location=None,
        tools="hover",
        tooltips="@x",
        y_range=factors,
        x_range=[0, 22],
        plot_width=700,
        plot_height=450)

    fig.segment(0, factors, x, factors, line_width=5, line_color="#3182bd")
    fig.circle(x, factors, size=30, fill_color="#9ecae1", line_color="#3182bd", line_width=8)
    fig.xgrid.grid_line_color = None
    fig.ygrid.grid_line_color = None
    return fig

def shuliang():
    cities = list(data['城市'].unique())
    cities_count = list(data['城市'].value_counts())
    zipped = zip(cities, cities_count)
    shuliang = (
        Bar(init_opts=opts.InitOpts(width='800px', height='500px'))
            .add_xaxis(cities).
            add_yaxis('职位需求数量', cities_count, category_gap='30%', color='#525288')
            .reversal_axis()
            .set_global_opts(
            xaxis_opts=opts.AxisOpts(is_show=True),
            yaxis_opts=opts.AxisOpts(is_show=True,
                                     axisline_opts=opts.AxisLineOpts(is_show=False),
                                     axistick_opts=opts.AxisTickOpts(is_show=False)),
            title_opts=opts.TitleOpts(
                title='职位需求数量城市差异',
                pos_left='9%',
                pos_top='2%',
                title_textstyle_opts=opts.TextStyleOpts(
                    color='#126bae', font_size=24)
            ),

        )
            .set_series_opts(
            itemstyle_opts={
                "normal": {
                    "barBorderRadius": [30, 30, 30, 30],
                    "shadowColor": "rgb(0, 160, 221)",
                }},
            label_opts=opts.LabelOpts(is_show=True,position='insideRight'),
        )
            .set_global_opts(title_opts=opts.TitleOpts(title="所有城市数据分析岗位平均薪资（千/月）",
                                                       pos_left="center", pos_bottom=10,
                                                       title_textstyle_opts=opts.TextStyleOpts(font_size=20)),
                             ))
    grid = (
        Grid(init_opts=opts.InitOpts(width='1000px', height='600px'))
            .add(shuliang, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        plot_all = "".join(f.readlines())
        return plot_all

def fenbu():
    cities = list(data['城市'].unique())
    cities_count = list(data['城市'].value_counts())
    zipped = zip(cities, cities_count)
    urban = [list(z) for z in zipped]
    reli = (
        Geo()
            .add_schema(maptype="china")
            .add(
            "职位需求数量", urban,
            type_=ChartType.HEATMAP,
        )
            .set_global_opts(
            visualmap_opts=opts.VisualMapOpts(
                max_=2500,
                min_=0,
                is_piecewise=True,
                split_number=4,
            ),
            title_opts=opts.TitleOpts(
                title="职位需求——城市分布"
            )
        )
    )
    grid1 = (
        Grid(init_opts=opts.InitOpts(width='600px', height='500px'))
            .add(reli, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid1.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        plot = "".join(f.readlines())
        return plot

def chengshishuliang():
    cities = list(data['城市'].unique())
    cities_count = list(data['城市'].value_counts())
    zipped = zip(cities, cities_count)
    urban = [list(z) for z in zipped]
    shuliang_fenbu = (
        Geo()
            .add_schema(maptype="china")
            .add(
            "职位需求数量",
            urban,
            type_=ChartType.EFFECT_SCATTER,
        )
            .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
            .set_global_opts(
            visualmap_opts=opts.VisualMapOpts(
                max_=2450,
                min_=80,
                is_piecewise=True,
                split_number=3,
                range_color=['#869d9d', '#a35c8f', '#a7535a'],
            ),
            title_opts=opts.TitleOpts(
                title="具体城市职位需求数量"
            )
        ))
    grid2 = (
        Grid(init_opts=opts.InitOpts(width='600px', height='500px'))
            .add(shuliang_fenbu, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid2.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        fenbu = "".join(f.readlines())
        return fenbu

def xizi():
    data['平均工资'] = (data['最高工资'] + data['最低工资']) / 2
    salary_average = data.groupby('城市')['平均工资'].mean().to_frame('平均工资').reset_index()
    salary_average['平均工资'] = salary_average['平均工资'].round(decimals=1)
    salary_average = salary_average.sort_values('平均工资', ascending=False)[:10]
    x_data = salary_average['城市'].values.tolist()
    y_data = salary_average['平均工资'].values.tolist()

    color_js1 = """new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                                offset: 0,
                                color: '#ede3e7'
                            }, {
                                offset: 1,
                                color: '#e6d2d5'
                            }], false)"""

    pingjunxinzi = (
        Bar(
            init_opts=opts.InitOpts(
                bg_color=JsCode(color_js1),
                width='1000px',
                height='600px'))
            .add_xaxis(x_data)
            .add_yaxis('千/月',
                       y_data,
                       category_gap="50%",
                       color='#ad6598'
                       )
            .set_series_opts(
            itemstyle_opts={
                "normal": {
                    "barBorderRadius": [30, 30, 30, 30],
                }
            })
            .set_global_opts(title_opts=opts.TitleOpts(title="所有城市数据分析岗位平均薪资（千/月）",
                                                       pos_left="center",
                                                       title_textstyle_opts=opts.TextStyleOpts(font_size=20)),
                             legend_opts=opts.LegendOpts(is_show=False)))
    grid = (
        Grid(init_opts=opts.InitOpts(width='800px', height='500px'))
            .add(pingjunxinzi, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        plot_all = "".join(f.readlines())
        return plot_all

def gongsi_leixing():
    data = read_data()
    leixing = list(data['公司类型'].unique())
    leixing_count = list(data['公司类型'].value_counts())
    gongsileixing = (Pie(init_opts=opts.InitOpts(width="800px", height="600px"))
        .add(
        series_name="公司类型",
        data_pair=[list(z) for z in zip(leixing, leixing_count)],
        radius=["50%", "70%"],
        label_opts=opts.LabelOpts(is_show=True),
    )
        .set_global_opts(legend_opts=opts.LegendOpts(pos_left="legft", orient="vertical"))
        .set_series_opts(
        tooltip_opts=opts.TooltipOpts(
            trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"
        ),
    )
    )
    grid = (
        Grid(init_opts=opts.InitOpts(width='800px', height='600px'))
            .add(gongsileixing, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        plot_all = "".join(f.readlines())
        return plot_all

def xuelipinjun():

    data['平均工资'] = (data['最高工资'] + data['最低工资']) / 2
    salary_average = data.groupby('学历')['平均工资'].mean().to_frame('平均工资').reset_index()
    salary_average['平均工资'] = salary_average['平均工资'].round(decimals=1)
    salary_average = salary_average.sort_values('平均工资', ascending=False)[:10]

    x_data = salary_average['学历'].values.tolist()
    y_data = salary_average['平均工资'].values.tolist()
    xuelixinzi = (
        Line()
            .add_xaxis(xaxis_data=x_data)
            .add_yaxis(
            series_name="",
            y_axis=y_data,
            symbol="emptyCircle",
            is_symbol_show=True,
            label_opts=opts.LabelOpts(is_show=False),
            areastyle_opts=opts.AreaStyleOpts(opacity=1, color="#f1939c"),
        )
            .set_global_opts(
            tooltip_opts=opts.TooltipOpts(is_show=True),
            yaxis_opts=opts.AxisOpts(
                type_="value",
                axistick_opts=opts.AxisTickOpts(is_show=True),
                splitline_opts=opts.SplitLineOpts(is_show=True),
            ),
            title_opts=opts.TitleOpts(title="学历平均薪资（千/月）",
                                      pos_left="center",
                                      title_textstyle_opts=opts.TextStyleOpts(font_size=20)),
            xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False)
        ))
    grid = (
        Grid(init_opts=opts.InitOpts(width='700px', height='500px'))
            .add(xuelixinzi, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        xueli_xinzi = "".join(f.readlines())
        return xueli_xinzi

def xuelifenlei():
    xueli = list(data['学历'].unique())
    xueli_count = list(data['学历'].value_counts())

    xuelifenlei = (
        Pie(init_opts=opts.InitOpts(width="700px", height="500px"))
            .add(
            series_name="学历要求",
            data_pair=[list(z) for z in zip(xueli, xueli_count)],
            radius=["50%", "70%"],
            label_opts=opts.LabelOpts(is_show=True, ),
        )
            .set_global_opts(legend_opts=opts.LegendOpts(pos_left="legft", orient="vertical"))
            .set_series_opts(
            tooltip_opts=opts.TooltipOpts(
                trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"
            ),
        )

    )
    grid = (
        Grid(init_opts=opts.InitOpts(width='700px', height='500px'))
            .add(xuelifenlei, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        xueli_data = "".join(f.readlines())
        return xueli_data

def hangyeciyun():
    hangye = list(data['所属行业'].unique())
    hangye_count = list(data['所属行业'].value_counts())
    zong = [list(z) for z in zip(hangye, hangye_count)]
    hangye_ciyun = (
        WordCloud()
            .add(series_name="行业", data_pair=zong, word_size_range=[10, 60])
            .set_global_opts(
            title_opts=opts.TitleOpts(
                title="所属行业词云图", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
            ),
            tooltip_opts=opts.TooltipOpts(is_show=True),
        )
    )
    grid = (
        Grid(init_opts=opts.InitOpts(width='700px', height='500px'))
            .add(hangye_ciyun, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        hangye_data = "".join(f.readlines())
        return hangye_data

def hangyeshuliang():
    guimo = list(data['公司规模'].unique())
    guimo = custom_sort(guimo)
    guimo_count = list(data['公司规模'].value_counts())
    c = (
        EffectScatter()
            .add_xaxis(guimo)
            .add_yaxis("", guimo_count, symbol=SymbolType.ARROW)
            .set_global_opts(title_opts=opts.TitleOpts())
    )
    grid = (
        Grid(init_opts=opts.InitOpts(width='700px', height='500px'))
            .add(c, grid_opts=opts.GridOpts(pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        gongsiguimo = "".join(f.readlines())
        return gongsiguimo

def hangyezhanbi():
    guimo = list(data['公司规模'].unique())
    guimo = custom_sort(guimo)
    guimo_count = list(data['公司规模'].value_counts())
    y_data = [24, 23, 14, 13, 12, 6, 5, 3]
    guimo_data = [[guimo[i], y_data[i]] for i in range(len(guimo))]
    loudou = (
        Funnel(init_opts=opts.InitOpts(width="700px", height="550px"))
            .add(
            series_name="",
            data_pair=guimo_data,
            gap=2,
            tooltip_opts=opts.TooltipOpts(trigger="item", formatter="<br/>{b} : {c}%"),
            label_opts=opts.LabelOpts(is_show=True, position="inside"),
            itemstyle_opts=opts.ItemStyleOpts(border_color="#fff", border_width=1),
        )
            .set_global_opts(title_opts=opts.TitleOpts(), )
    )
    grid = (
        Grid(init_opts=opts.InitOpts(width='700px', height='500px'))
            .add(loudou, grid_opts=opts.GridOpts(pos_right='10%', pos_left='20%'))
    )
    grid.render("example.html")
    with open("example.html", encoding="utf8", mode="r") as f:
        guimozhanbi = "".join(f.readlines())
        return guimozhanbi
